package com.dycong.common.strategy.support;

import com.dycong.common.strategy.Strategy;
import com.google.common.collect.ImmutableTable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 策略生产的工厂
 *
 * @author GengChao
 * @email chao_geng@sui.com
 * @date 2018/6/8
 */
@Slf4j
@Lazy
@Component
public class StrategyFactory implements ApplicationContextAware {

    /**
     * 存储对应的枚举和策略处理类的关系
     */
    private static ImmutableTable<BizModuleEnum, String, Strategyable> strategys;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ImmutableTable.Builder<BizModuleEnum, String, Strategyable> immutableTableBuilder = ImmutableTable.builder();

        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Strategy.class);
        for (Map.Entry<String, Object> entry : beans.entrySet()) {
            String beanName = entry.getKey();
            Object bean = entry.getValue();

            if (bean instanceof Strategyable) {
                Strategy av = applicationContext.findAnnotationOnBean(beanName, Strategy.class);
                Strategyable strategyable = (Strategyable) bean;
                BizModuleEnum moduleEnum = av.bizType();
                String beanQualifier = strategyable.beanQualifier();
                immutableTableBuilder.put(moduleEnum, beanQualifier, strategyable);
            }
            strategys = immutableTableBuilder.build();
        }

    }


    public <I extends Strategyable> I matchingStrategy(BizModuleEnum moduleEnum, String beanQualifier) {
        return (I) strategys.get(moduleEnum, beanQualifier);
    }

}
